home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
- * Copying of this file is granted according to the provisions
- * specified in the file COPYING which must accompany this file.
- */
-
-
- /*
- * pack.c
- */
-
- #include "tex.h"
- #include "heap.h"
- #include "arith.h"
- #include "scan.h"
- #include "tokenstack.h"
- #include "eq.h"
- #include "eqstack.h"
- #include "evalstack.h"
- #include "box.h"
- #include "tfm.h"
- #include "dvi.h"
- #include "print.h"
- #include "error.h"
- #include "pack.h"
-
- ptr adjust_tail;
- val pack_begin_line;
- scal total_shrink[4];
- scal total_stretch[4];
-
- #define clr_dimens() \
- {d = x = 0; \
- total_stretch[FILLL] = 0; \
- total_stretch[FILL] = 0; \
- total_stretch[FIL] = 0; \
- total_stretch[NORMAL] = 0; \
- total_shrink[FILLL] = 0; \
- total_shrink[FILL] = 0; \
- total_shrink[FIL] = 0; \
- total_shrink[NORMAL] = 0;}
-
- ptr
- hpack (p, w, m)
- ptr p;
- scal w;
- int m;
- {
- int b;
- scal d;
- fnt f;
- ptr g;
- scal h;
- fourq i;
- gord o;
- ptr q;
- ptr r;
- scal s;
- scal x;
- byte hd;
-
- r = get_node(BOX_NODE_SIZE);
- type(r) = HLIST_NODE;
- subtype(r) = MIN_QUARTERWORD;
- shift_amount(r) = 0;
- q = r + LIST_OFFSET;
- link(q) = p;
- h = 0;
- clr_dimens();
- while (p != NULL) {
- reswitch:
- while (is_char_node(p)) {
- f = font(p);
- i = char_info(f, character(p));
- hd = height_depth(i);
- x += char_width(f, i);
- s = char_height(f, hd);
- if (s > h)
- h = s;
- s = char_depth(f, hd);
- if (s > d)
- d = s;
- p = link(p);
- }
- if (p != NULL) {
- switch (type(p))
- {
- case HLIST_NODE:
- case VLIST_NODE:
- case RULE_NODE:
- case UNSET_NODE:
- x += width(p);
- if (type(p) >= RULE_NODE)
- s = 0;
- else s = shift_amount(p);
- if (height(p) - s > h)
- h = height(p) - s;
- if (depth(p) + s > d)
- d = depth(p) + s;
- break;
-
- case INS_NODE:
- case MARK_NODE:
- case ADJUST_NODE:
- if (adjust_tail != NULL) {
- while (link(q) != p)
- q = link(q);
- if (type(p) == ADJUST_NODE) {
- link(adjust_tail) = adjust_ptr(p);
- while (link(adjust_tail) != NULL)
- adjust_tail = link(adjust_tail);
- p = link(p);
- free_node(link(q), SMALL_NODE_SIZE);
- } else {
- link(adjust_tail) = p;
- adjust_tail = p;
- p = link(p);
- }
- link(q) = p;
- p = q;
- }
- break;
-
- case WHATSIT_NODE:
- break;
-
- case GLUE_NODE:
- g = glue_ptr(p);
- x += width(g);
- o = stretch_order(g);
- total_stretch[o] += stretch(g);
- o = shrink_order(g);
- total_shrink[o] += shrink(g);
- if (subtype(p) >= A_LEADERS) {
- g = leader_ptr(p);
- if (height(g) > h)
- h = height(g);
- if (depth(g) > d)
- d = depth(g);
- }
- break;
-
- case KERN_NODE:
- case MATH_NODE:
- x += width(p);
- break;
-
- case LIGATURE_NODE:
- make_char_from_lig();
- goto reswitch;
- break;
-
- default:
- break;
- }
- p = link(p);
- }
- }
- if (adjust_tail != NULL)
- link(adjust_tail) = NULL;
- height(r) = h;
- depth(r) = d;
- if (m == ADDITIONAL)
- w += x;
- width(r) = w;
- x = w - x;
- if (x == 0) {
- glue_sign(r) = NORMAL;
- glue_order(r) = NORMAL;
- glue_set(r) = 0.0;
- return r;
- } else if (x > 0) {
- get_stretch_order();
- glue_order(r) = o;
- glue_sign(r) = STRETCHING;
- if (total_stretch[o] != 0)
- glue_set(r) = (float) x / total_stretch[o];
- else {
- glue_sign(r) = NORMAL;
- glue_set(r) = 0.0;
- }
- if (hbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
- b = badness(x, total_stretch[NORMAL]);
- if (b > hbadness) {
- print_ln();
- if (b > 100)
- print_nl("Underfull");
- else print_nl("Loose");
- print(" \\hbox (badness ");
- print_int(b);
- goto common_end;
- }
- }
- return r;
- } else {
- get_shrink_order();
- glue_order(r) = o;
- glue_sign(r) = SHRINKING;
- if (total_shrink[o] != 0)
- glue_set(r) = (float) -x / total_shrink[o];
- else {
- glue_sign(r) = NORMAL;
- glue_set(r) = 0.0;
- }
- if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
- glue_set(r) = 1.0;
- if (-x - total_shrink[NORMAL] > hfuzz || hbadness < 100) {
- if (overfull_rule > 0 && -x - total_shrink[NORMAL] > hfuzz) {
- while (link(q) != NULL)
- q = link(q);
- link(q) = new_rule();
- width(link(q)) = overfull_rule;
- }
- print_ln();
- print_nl("Overfull \\hbox (");
- print_scaled(-x - total_shrink[NORMAL]);
- print("pt too wide");
- goto common_end;
- }
- } else if (hbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
- b = badness(-x, total_shrink[NORMAL]);
- if (b > hbadness) {
- print_ln();
- print_nl("Tight \\hbox (badness ");
- print_int(b);
- goto common_end;
- }
- }
- return r;
- }
-
- common_end:
- if (output_active)
- print(") has occurred while \\output is active");
- else {
- if (pack_begin_line != 0) {
- if (pack_begin_line > 0)
- print(") in paragraph at lines ");
- else print(") in alignment at lines ");
- print_val(abs(pack_begin_line));
- print("--");
- } else print(") detected at line ");
- print_val(line);
- }
- print_ln();
- font_in_short_display = NULL_FONT;
- short_display(list_ptr(r));
- print_ln();
- begin_diagnostic();
- show_box(r);
- end_diagnostic(TRUE);
- return r;
- }
-
- ptr
- vpackage (p, h, m, l)
- ptr p;
- scal h;
- int m;
- scal l;
- {
- int b;
- scal d;
- ptr g;
- gord o;
- ptr r;
- scal s;
- scal w;
- scal x;
-
- r = get_node(BOX_NODE_SIZE);
- type(r) = VLIST_NODE;
- subtype(r) = MIN_QUARTERWORD;
- shift_amount(r) = 0;
- list_ptr(r) = p;
- w = 0;
- clr_dimens();
- while (p != NULL) {
- if (is_char_node(p))
- confusion("vpack");
- else {
- switch (type(p))
- {
- case HLIST_NODE:
- case VLIST_NODE:
- case RULE_NODE:
- case UNSET_NODE:
- x += d + height(p);
- d = depth(p);
- if (type(p) >= RULE_NODE)
- s = 0;
- else s = shift_amount(p);
- if (width(p) + s > w)
- w = width(p) + s;
- break;
-
- case WHATSIT_NODE:
- break;
-
- case GLUE_NODE:
- x += d;
- d = 0;
- g = glue_ptr(p);
- x += width(g);
- o = stretch_order(g);
- total_stretch[o] += stretch(g);
- o = shrink_order(g);
- total_shrink[o] += shrink(g);
- if (subtype(p) >= A_LEADERS) {
- g = leader_ptr(p);
- if (width(g) > w)
- w = width(g);
- }
- break;
-
- case KERN_NODE:
- x += d + width(p);
- d = 0;
- break;
-
- default:
- break;
- }
- p = link(p);
- }
- }
- width(r) = w;
- if (d > l) {
- x += d - l;
- depth(r) = l;
- } else depth(r) = d;
- if (m == ADDITIONAL)
- h += x;
- height(r) = h;
- x = h - x;
- if (x == 0) {
- glue_sign(r) = NORMAL;
- glue_order(r) = NORMAL;
- glue_set(r) = 0.0;
- return r;
- } else if (x > 0) {
- get_stretch_order();
- glue_order(r) = o;
- glue_sign(r) = STRETCHING;
- if (total_stretch[o] != 0)
- glue_set(r) = (float) x / total_stretch[o];
- else {
- glue_sign(r) = NORMAL;
- glue_set(r) = 0.0;
- }
- if (vbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
- b = badness(x, total_stretch[NORMAL]);
- if (b > vbadness) {
- print_ln();
- if (b > 100)
- print_nl("Underfull");
- else print_nl("Loose");
- print(" \\vbox (badness ");
- print_int(b);
- goto common_end;
- }
- }
- return r;
- } else {
- get_shrink_order();
- glue_order(r) = o;
- glue_sign(r) = SHRINKING;
- if (total_shrink[o] != 0)
- glue_set(r) = (float) -x / total_shrink[o];
- else {
- glue_sign(r) = NORMAL;
- glue_set(r) = 0.0;
- }
- if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
- glue_set(r) = 1.0;
- if (-x - total_shrink[NORMAL] > vfuzz || vbadness < 100) {
- print_ln();
- print_nl("Overfull \\vbox (");
- print_scaled(-x - total_shrink[NORMAL]);
- print("pt too high");
- goto common_end;
- }
- } else if (vbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
- b = badness(-x, total_shrink[NORMAL]);
- if (b > vbadness) {
- print_ln();
- print_nl("Tight \\vbox (badness ");
- print_int(b);
- goto common_end;
- }
- }
- return r;
- }
-
- common_end:
- if (output_active)
- print(") has occurred while \\output is active");
- else {
- if (pack_begin_line != 0) {
- print(") in alignment at lines ");
- print_val(abs(pack_begin_line));
- print("--");
- } else print(") detected at line ");
- print_val(line);
- print_ln();
- }
- begin_diagnostic();
- show_box(r);
- end_diagnostic(TRUE);
- return r;
- }
-